JSR303 参数校验
参数校验提供了一些简单的注解,可以对前端传递过来的参数进行验证,并且自定义异常信息。常用的注解有:
- @Min(value=””,message=””)
- @Max
- @Range
- @Length
开启参数校验
验证简单的参数
- 在类(Controller)上添加@Validated,开启参数校验
- 在方法的参数上使用@Min等验证注解
验证DTO中的参数
- 在方法参数上(一般是Controller中的方法)添加@Validated,开启参数校验
- 在DTO的成员变量上添加验证注解
级联校验
- 在方法参数上(一般是Controller中的方法)添加@Validated,开启参数校验
- 在验证的DTO中关联的DTO上加@Valid,开启级联校验
- 在关联的DTO中添加验证注解
需要说明的一点是,DTO是用服务器用来接收前端传递过来的参数的,可以通过把相关联的DTO属性加入到同一个DTO,从而消除级联的校验。
@Validated与@Valid的区别:
- 它们具有一定的相似性,并不是互斥的关系,在一定情况下可以互换使用
- @Valid是Java标准,而@Validated是Spring对@Valid的扩展
- 一般情况下,@Validate用于开启参数校验,@Valid用于开启级联校验
自定义校验注解
自定义一个注解,加上模板方法groups、payloads
1
2
3Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};注解上添加@Constraint(validatedBy = xxxx.class),关联一个类,用来编写校验逻辑
定义一个类,实现ConstraintValidator<T,R>接口,泛型T表示自定义注解的类型,*泛型R表示自定义注解修饰的目标的类型。
实现isValid的方法,返回boolean值标志是否通过校验
如果需要获取注解中定义的参数,要实现initialize方法,将注解的数据赋值给成员变量,这样在isValid方法中就可以获取注解中的信息进行判断
一个自定义校验注解的栗子
自定义一个注解,加上模板方法groups、payloads,注解上添加@Constraint(validatedBy = xxxx.class),关联一个类,用来编写校验逻辑。
1 |
|
定义一个类编写校验的相关逻辑,T是自定义注解的类型,R是自定义注解修饰的目标的类型。
1 | public class PasswordEqualValidator implements ConstraintValidator<PasswordEqual, PersonDTO> { |
完成自定义注解的编写后,在PersonDTO中使用:
记得开启参数校验,参考上面“开启参数校验”这一章节。
1 |
|
参数校验结合全局异常处理
参数校验分为两种情况:
- POST请求通过body传递的参数
- GET请求通过url传递的参数
POST Body 传递的参数校验异常处理
- 抛出MethodArgumentNotValidException
- 存在校验有多个错误信息的可能,需要将所有的错误信息拼接成字符串返回
- List
中getDefaultMessage可以获取到错误信息
1 | /** |
通过url传递的参数校验异常处理
一是使用SpingBoot默认的message
1 | /** |
二是自己处理的message:
1 | private String getConstraintViolationMessage(ConstraintViolationException e){ |
抽取出message配置模板
在resources目录下,创建一个ValidationMessages.properties文件(规定了只能是这个文件)。
注意,在这里用{}来引用配置文件中的key。在配置文件中,也能使用{}来引入注解中的值。
1 | id.positive=id不能为负数{max}{min} |
1 | "name/{name}") (value = |